package my.mybatis.common;


import my.mybatis.common.request.BaseRequestParam;
import my.mybatis.common.util.GenericsUtils;
import my.mybatis.common.util.QueryBuildFactory;

import java.io.Serializable;

/**
 * @Author:wangbin.
 * @Description. 查询参数转换
 * @Date:Created in 14:00 2018/1/22.
 * @Modified By:
 */
public abstract class BaseService<T> implements Serializable {
    private static final long serialVersionUID = 4535729205971939185L;

    protected final ThreadLocal<QueryParams> threadLocalQueryParams = new ThreadLocal<QueryParams>();

    /**
     * 获取查询条件参数（指定类型的查询条件参数）
     * @param clazz
     * @return
     */
    protected final QueryParams getQueryParams(Class clazz)
    {
        return QueryBuildFactory.createQueryParams(clazz);
    }

    /**
     * 获取查询条件参数(默认获取当前service对应的实体类的查询条件)
     * @return
     */
    protected final QueryParams getQueryParams()
    {
        QueryParams queryParams = threadLocalQueryParams.get();
        if(queryParams == null)
        {
            queryParams = QueryBuildFactory.createQueryParams(GenericsUtils.getSuperClassGenricType(getClass()));
            threadLocalQueryParams.set(queryParams);
        }
        return queryParams;
    }
    /**
     * 通过BaseRequestParam 构造查询条件，查询排序
     * @param baseRequestParam
     * @return
     */
    protected final QueryParams getQueryParams(BaseRequestParam baseRequestParam)
    {
        QueryParams queryParams = getQueryParams();
        // 排序参数的设置
        if(baseRequestParam.getOrderParam() != null && baseRequestParam.getOrderParam().size() > 0)
            queryParams.setOrderParams(baseRequestParam.getOrderParam());
        else
            // 添加默认排序
            addOrderParams();

        // 条件参数的设置
        queryParams.setQueryParams(baseRequestParam.getQueryParam());

        if(baseRequestParam.getParam() != null)
        {
            // 此处可以将dto中对应的属性add到searchParams中,这样做就不用在xml中修改sql语句了。添加方式如下：
            addQueryParamsByParam(baseRequestParam.getParam());
        }
        return queryParams;
    }

    /**
     * 重置条件参数(在每个方法中，如果要构建QueryParams参数，需要先调用此方法)
     */
    protected final void resetQueryParams()
    {
        if(threadLocalQueryParams.get() == null)
            threadLocalQueryParams.set(QueryBuildFactory.createQueryParams(GenericsUtils.getSuperClassGenricType(getClass())));
        else
        {
            threadLocalQueryParams.remove();
            threadLocalQueryParams.set(QueryBuildFactory.createQueryParams(GenericsUtils.getSuperClassGenricType(getClass())));
        }
    }

    /**
     * 直接构造查询参数并添加
     * @param param
     */
    protected final void addQueryParam(QueryParam param)
    {
        threadLocalQueryParams.get().addQueryParam(param);
    }

    /**
     * 直接设置查询
     * key：属性名；
     * operator：查询条件；
     * value：查询条件值
     * @see QueryParam.Builder
     * @param key
     * @param operator
     * @param value
     */
    protected final void addQueryParam(String key, String operator, Object value)
    {
        addQueryParam(QueryBuildFactory.createQueryParam().key(key).operator(operator).value(value).build());
    }

    /**
     * 直接构造排序参数并添加
     * @param param
     */
    protected final void addOrderParam(OrderParam param){
        threadLocalQueryParams.get().addOrderParam(param);
    }

    /**
     * 直接设置排序查询
     * orderByKey: 排序字段
     * descOrAsc： 排序规则
     * @see OrderParam
     * @param orderByKey
     * @param descOrAsc
     */
    protected final void addOrderParam(String orderByKey,String descOrAsc)
    {
        addOrderParam(QueryBuildFactory.createOrderParam().orderBy(orderByKey).ascOrDesc(descOrAsc).build());
    }

    /**
     * 添加排序参数
     */
    protected abstract void addOrderParams();

    /**
     * 根据实体类参数转换条件参数
     * @param param
     */
    protected abstract void addQueryParamsByParam(Object param);

    /**
     * 指定当前service服务对应的entity
     * @return
     */
    protected abstract Class getClazz();
}
